1、 pinctrl 架构
	pinctrl 框架分为两个部分，分别是引脚复用控制器 pinctrl_dev 和使用引脚的 pinctrl client。
	pinctrl_dev ：提供服务，可以用它来复用引脚、配置引脚
	pinctrl client ：使用服务，即使用 Pinctrl 系统的设备
2、 struct pinctrl_dev 对象
	pinctrl_dev 表示一个引脚复用控制器，核心成员如下：
	//描述 pinctrl_dev
	struct pinctrl_desc *desc;
	//指向父设备对象
	struct device *dev;
	//pinctrl_gpio_range 类型的链表，描述 GPIO 子系统中的 GPIO 编号与 pinctrl 控制器中的引脚编号的对应关系
	struct list_head gpio_ranges;
3、 struct pinctrl_desc 对象
	pinctrl_desc 对象用于描述一个 pinctrl_dev ，其核心成员如下：
	//名称
	const char *name;
	//描述引脚的数组，对于单个引脚的获取通过此参数实现
	const struct pinctrl_pin_desc *pins;
	//引脚描述数组的长度
	unsigned int npins;
	//操作函数集合，主要用于获取引脚组的引脚和处理设备树
	const struct pinctrl_ops *pctlops;
	//操作函数集合，引脚复用功能选择和 GPIO 相关操作
	const struct pinmux_ops *pmxops;
	//操作函数集合，引脚配置
	const struct pinconf_ops *confops;
4、 struct pinctrl_ops 对象
	pinctrl_ops 对象主要实现获取引脚组的引脚、设备树映射和取消映射的功能，其核心成员如下：
	//获取引脚组数量
	int (*get_groups_count) (struct pinctrl_dev *pctldev);
	//获取指定引脚组的名称
	const char *(*get_group_name) (struct pinctrl_dev *pctldev, unsigned selector);
	//获取指定引脚组的引脚，引脚通过 pins 数组返回，
	int (*get_group_pins) (struct pinctrl_dev *pctldev, unsigned selector,
		const unsigned **pins, unsigned *num_pins);
	//解析设备树的引脚配置节点并进行映射
	int (*dt_node_to_map) (struct pinctrl_dev *pctldev, struct device_node *np_config, 
		struct pinctrl_map **map, unsigned *num_maps);
	//释放 dt_node_to_map 创建的映射
	void (*dt_free_map) (struct pinctrl_dev *pctldev, struct pinctrl_map *map, unsigned num_maps);
5、 struct pinmux_ops 对象
	pinmux_ops 对象主要实现引脚复用功能选择和 GPIO 操作相关功能，其核心成员如下：
	//获取引脚
	int (*request) (struct pinctrl_dev *pctldev, unsigned offset);
	//释放引脚
	int (*free) (struct pinctrl_dev *pctldev, unsigned offset);
	//返回引脚支持多少种复用功能
	int (*get_functions_count) (struct pinctrl_dev *pctldev);
	//返回指定复用功能的名称
	const char *(*get_function_name) (struct pinctrl_dev *pctldev, unsigned selector);
	//返回支持此复用功能的引脚组
	int (*get_function_groups) (struct pinctrl_dev *pctldev,
		unsigned selector,
		const char * const **groups,
		unsigned *num_groups);
	//设置引脚复用功能
	int (*set_mux) (struct pinctrl_dev *pctldev,
		unsigned func_selector,
		unsigned group_selector);
	//在指定引脚上启用 GPIO 功能
	int (*gpio_request_enable) (struct pinctrl_dev *pctldev,
		struct pinctrl_gpio_range *range,
		unsigned offset);
	//与 gpio_request_enable 操作相反
	void (*gpio_disable_free) (struct pinctrl_dev *pctldev,
		struct pinctrl_gpio_range *range,
		unsigned offset);
	//配置 GPIO 方向
	int (*gpio_set_direction) (struct pinctrl_dev *pctldev, 
		struct pinctrl_gpio_range *range,
		unsigned offset,
		bool input);
6、 struct pinconf_ops 对象
	pinconf_ops 对象主要实现引脚配置（主要用于配置电气特性）相关功能，其核心成员如下：
	//获取引脚当前配置
	int (*pin_config_get) (struct pinctrl_dev *pctldev,
		unsigned pin,
		unsigned long *config);
	//配置指定引脚
	int (*pin_config_set) (struct pinctrl_dev *pctldev,
		unsigned pin,
		unsigned long *configs,
		unsigned num_configs);
	//获取引脚组的当前配置
	int (*pin_config_group_get) (struct pinctrl_dev *pctldev,
		unsigned selector,
		unsigned long *config);
	//配置指定引脚组
	int (*pin_config_group_set) (struct pinctrl_dev *pctldev,
		unsigned selector,
		unsigned long *configs,
		unsigned num_configs);
	//在 debugfs 中为指定引脚提供设备信息
	void (*pin_config_dbg_show) (struct pinctrl_dev *pctldev,
		struct seq_file *s,
		unsigned offset);
7、注册/注销 pinctrl_dev 
	注册： 
	struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, 
		struct device *dev, void *driver_data)
	struct pinctrl_dev *devm_pinctrl_register(struct device *dev,
		struct pinctrl_desc *pctldesc, void *driver_data)
	注销：
		void pinctrl_unregister(struct pinctrl_dev *pctldev)
8、 dev_pin_info 对象
	在 device 对象中包含一个 dev_pin_info 对象，它用于暂存 device 所引用的 pinctrl 信息，其主要成员如下：
	//指向设备的 pinctrl 信息，一般一个 device 包含一个 pinctrl 对象，相应的也只有一个 dev_pin_info 对象
	struct pinctrl *p;
	//默认的 pinctrl 状态
	struct pinctrl_state *default_state;
	//初始化的 pinctrl 状态
	struct pinctrl_state *init_state;
	//睡眠的 pinctrl 状态
	struct pinctrl_state *sleep_state;
	//空闲的 pinctrl 状态
	struct pinctrl_state *idle_state;
9、 pinctrl 对象
	pinctrl 对象用于描述设备的 pinctrl 信息，其主要成员如下：
	//链表节点，用于构成链表
	struct list_head node;
	//所属设备
	struct device *dev;
	//pinctrl_state 链表，一个 pinctrl 一般包含多个状态
	struct list_head states;
	//当前状态
	struct pinctrl_state *state;
	//pinctrl_map 链表，包含从设备树中的到的一系列的 pinctrl_map ，这些 pinctrl_map 在转换为 pinctrl_setting
	//后按 pinctrl_map 的名称归类到相应的 pinctrl_state 中
	struct list_head dt_maps;
10、 pinctrl_state 对象
	pinctrl_state 对象用于描述 pinctrl 信息中的状态信息，其核心成员如下：
	//链表节点，用于构成链表
	struct list_head node;
	//此状态的名字
	const char *name;
	//pinctrl_setting 链表，包含一系列 pinctrl_setting
	struct list_head settings;
11、 pinctrl_setting 对象
	pinctrl_setting 对象用于描述 pinctrl_state 的配置信息，其核心成员如下：
	//链表节点，用于构成链表
	struct list_head node;
	//pinctrl_setting 类型
	enum pinctrl_map_type type;
	//所属的 pinctrl_dev
	struct pinctrl_dev *pctldev;
	//使用此 pinctrl_setting 的设备的名称
	const char *dev_name;
	union {
		//引脚复用信息
		struct pinctrl_setting_mux mux;
		//引脚配置信息
		struct pinctrl_setting_configs configs;
	} data;
12、 pinctrl_map 对象
	pinctrl_map 对象用于描述 pinctrl 的设备树信息，它通过调用 pinctrl_dev 的 dt_node_to_map 得到，然后又将其
转换为 pinctrl_setting ，其核心成员如下：
	//使用此 pinctrl_map 的设备的名称
	const char *dev_name;
	//pinctrl_map 的名称，按此名称归类到不同的 pinctrl_state 中
	const char *name;
	//pinctrl_map 的类型
	enum pinctrl_map_type type;
	//对应的 pinctrl_dev 名称
	const char *ctrl_dev_name;
	union {
		//引脚复用信息
		struct pinctrl_map_mux mux;
		//引脚配置信息
		struct pinctrl_map_configs configs;
	} data;
13、 dev_pin_info 构造过程
	设备和驱动匹配成功后，在调用驱动或总线的 probe 函数之前会先调用 int really_probe(struct device *dev, 
struct device_driver *drv) 函数，在此函数中会通过 pinctrl_bind_pins 构建 device 对象中的 dev_pin_info 对象，
其大至过程如下：
	pinctrl_bind_pins
		//为设备分配 dev_pin_info 对象
		devm_kzalloc(dev, sizeof(*(dev->pins)), GFP_KERNEL);
			devm_pinctrl_get
				pinctrl_get
					//创建 pinctrl 对象
					create_pinctrl
						//分配一个 pinctrl 对象
						kzalloc(sizeof(*p), GFP_KERNEL);
						//解析设备树，得到 pinctrl_map ，并将解析出来的 pinctrl_map 添加到 pinctrl_maps 链表
						//中
						pinctrl_dt_to_map
						//遍历 pinctrl_maps 链表，将与设备匹配的 pinctrl_map 转换为 pinctrl_setting
						 for_each_maps(maps_node, i, map)
							//转换时根据 pinctrl_map 名称将得到的 pinctrl_setting 归到相应的 pinctrl_state 中
							//即 pinctrl_map 的名称决定了它所转换出来的 pinctrl_setting 属于那个 pinctrl_state
							ret = add_setting(p, map)
